const http = require("http");
const Router = require("./router");
var request = require("./request");
var response = require("./response");
var middleware = require("./middleware/init");
var View = require("./view");
function Application() {
  this.settings = {};
  this.engines = {};
}
// 惰性创建路由
Application.prototype.lazyrouter = function() {
  if (!this._router) {
    this._router = new Router();
    this._router.use(middleware.init(this));
  }
};

Application.prototype.set = function(setting, val) {
  if (arguments.length === 1) {
    return this.settings[setting];
  }

  this.settings[setting] = val;
  return this;
};
// 应用级中间件
Application.prototype.use = function(fn) {
  var path = "/",
    router = this._router;
  //获取router
  this.lazyrouter();
  router = this._router;
  // 路径挂载
  if (typeof fn !== "function") {
    path = fn;
    fn = arguments[1] + "";
  }

  router.use(path, fn);
  return this;
};

// 监听网络端口
Application.prototype.listen = function(port, cb) {
  console.log("### project init");
  const self = this;
  const server = http.createServer((req, res) => {
    self.handle(req, res);
  });
  return server.listen.apply(server, arguments);
};

Application.prototype.handle = function(req, res) {
  var done = function finalhandler(err) {
    res.writeHead(404, {
      "Content-Type": "text/plain"
    });
    if (err) {
      res.end("404" + err);
    } else {
      var msg = `Cannot ${req.method} ${req.url}`;
      res.end(msg);
    }
  };
  var router = this._router;
  if (router) {
    router.handle(req, res, done);
  } else {
    done;
  }
  //   return this._router.handle(req, res, done);
};

// 设置模版引擎
Application.prototype.engine = function(ext, fn) {
  var extension = ext[0] !== "." ? "." + ext : ext;
  this.engines[extension] = fn;
  return this;
};

// 注册所有应用请求
http.METHODS.forEach(function(method) {
  method = method.toLocaleLowerCase();
  Application.prototype[method] = function(path, fn, next) {
    // 拦截设置
    if (method === "get" && arguments.length === 1) {
      return this.set(path);
    }

    this.lazyrouter();
    // 调用router的对应方法
    this._router[method].apply(this._router, arguments);
    return this;
  };
});

// 渲染引擎
Application.prototype.render = function(name, options, callback) {
  var done = callback;
  var engines = this.engines;
  var opts = options;
  view = new View(name, {
    defaultEngine: this.get("view engine"),
    root: this.get("views"),
    engines: engines
  });
  if (!view.path) {
    var err = new Error('Failed to lookup view"' + name + '"');
    return done(err);
  }

  try {
    view.render(options, callback);
  } catch (e) {
    callback(e);
  }
};

exports = module.exports = Application;
